package dao.impl;

import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.io.Serializable;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import dao.IGenericDAO;

public abstract class GenericDAO<T, ID extends Serializable> implements
		IGenericDAO<T, ID> {

	private Class<T> entityBeanType;
	
	@PersistenceContext (unitName="EJB Tutorial")
	private EntityManager em;

	@SuppressWarnings("unchecked")
	public GenericDAO() {
		this.entityBeanType = (Class<T>) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
	}

	
	public void setEntityManager(EntityManager em) {
		this.em = em;
	}

	protected EntityManager getEntityManager() {
		return em;
	}

	public Class<T> getPersistentClass() {
		return entityBeanType;
	}

	public T findById(ID id) {
		T entity;
		entity = (T) getEntityManager().find(getPersistentClass(), id);
		return entity;
	}

	@SuppressWarnings("unchecked")
	public List<T> findAll() {
		Query q = getEntityManager().createQuery(
				"select x from " + entityBeanType.getSimpleName() + " x");
		return q.getResultList();
	}

	public T makePersistent(T entity) {
		getEntityManager().persist(entity);			
		getEntityManager().flush();
		//getEntityManager().refresh(entity);
		return entity;
	}

	public void makeTransient(T entity) {
		getEntityManager().remove(entity);
	}

	public T merge(T entity) {
		return getEntityManager().merge(entity);
	}
	
	public void refresh(T entity) {
		getEntityManager().refresh(entity);
	}
	
	public void flush(){
		getEntityManager().flush();
	}
	
	public void commit(){
		this.getEntityManager().getTransaction().commit();
	}

	public void delete(T entity) {
		em.remove(entity);
	}
}
